//
//  ZJTestObject.m
//  SingletonTest
//
//  Created by ZJ on 2018/3/20.
//  Copyright © 2018年 iCatch Technology Inc. All rights reserved.
//

#import "ZJTestObject.h"

@interface ZJTestObject () <NSCopying, NSMutableCopying>

@property (nonatomic, assign) NSInteger height;
@property (nonatomic, strong) NSObject *object;
@property (nonatomic, strong) NSMutableArray *arrayM;

@end

@implementation ZJTestObject

static ZJTestObject *instance = nil;

#pragma mark - Method1

/**
 这种方法实现单例时，当使用 [ZJTestObject new] 或 [[ZJTestObject alloc] init] 单例对象的属性不能被初始化，***错误****
 */

//+ (instancetype)sharedTestObject {
//    static dispatch_once_t onceToken;
//    dispatch_once(&onceToken, ^{
//        instance = [[[self  class] alloc] init];
//        instance.height = 10;
//        instance.object = [[NSObject alloc] init];
//        instance.arrayM = [[NSMutableArray alloc] init];
//    });
//
//    return instance;
//}

//+ (instancetype)allocWithZone:(struct _NSZone *)zone {
//    static dispatch_once_t onceToken;
//    dispatch_once(&onceToken, ^{
//        instance = [super allocWithZone:zone];
//    });
//
//    return instance;
//}

#pragma mark - Method2

+ (instancetype)sharedTestObject {
    return [[self alloc] init];
}

+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [super allocWithZone:zone];
    });
    
    return instance;
}

- (instancetype)init
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [super init];
        if (self) {
            instance.height = 10;
            instance.object = [[NSObject alloc] init];
            instance.arrayM = [[NSMutableArray alloc] init];
        }
    });
    
    return instance;
}

#pragma mark - description
- (NSString *)description {
    NSString *result = @"";
    
    result = [result stringByAppendingFormat:@"<%@: %p>", [self class], self];
    result = [result stringByAppendingFormat:@" height = %zd,", self.height];
    result = [result stringByAppendingFormat:@" arrayM = %p,", self.arrayM];
    result = [result stringByAppendingFormat:@" object = %p,", self.object];
    
    return result;
}


/**
 当单例对象遵循了 NSCopying 或 NSMutableCopying 协议时，也需要保证对象的单一性

 */
#pragma mark - NSCopying
- (nonnull id)copyWithZone:(nullable NSZone *)zone {
    return instance;
}

#pragma mark - NSMutableCopying
- (nonnull id)mutableCopyWithZone:(NSZone *)zone {
    return instance;
}

@end
